#include "wrapper.h"
#include "pubfunc.h"
#include "merge.h"
#include "append.h"
#include "truncate.h"

Wrapper *Wrapper::wapper = 0;

Wrapper::Wrapper()
{
	connection = 0;
	tableMapping = 0;
	load = 0;
}

Wrapper::~Wrapper()
{
	clear();
}

int Wrapper::open(int argc, char **argv)
{		
	if (sigaction() != 0){
		return -1;
	}
	if (getopt(argc, argv) != 0){
		return -1;
	}
	if (open() != 0){
		return -1;
	}
	return 0;
}

int Wrapper::loadData()
{
	return load->load();
}

int Wrapper::getopt(int argc, char **argv)
{
	/*
	int rc;
		
	while (( rc = ::getopt(argc, argv, "i:u:p:c:")) != EOF){
		switch (rc){
		case 'i':
			sid = optarg;
			break;
		case 'u':
			user = optarg;
			break;
		case 'p':
			password = optarg;
			break;
		case 'c':
			configFile = optarg;
			break;
		case 'h':
		default:
			usage(argv[0]);
			return -1;
			break;
		}
	}
	*/
	int i;

	for (i=1; i<argc; i+=2){
		if (argv[i][0] != '-'){
			usage(argv[0]);
			return -1;
		}
		if (strlen(argv[i]) < 2){
			usage(argv[0]);
			return -1;
		}
		if ((i+1) >= argc){
			usage(argv[0]);
			return -1;
		}
		switch (argv[i][1]){
		case 'i':
			sid = argv[i+1];
			break;
		case 'u':
			user = argv[i+1];
			break;
		case 'p':
			password = argv[i+1];
			break;
		case 'c':
			configFile = argv[i+1];
			break;
		case 'h':
			usage(argv[0]);
			return -1;
			break;
		case '-':
			parameters[argv[i]+2] = argv[i+1];
			break;
		default:
			usage(argv[0]);
			return -1;
			break;
		}
	}
	
	if (sid == ""){
		usage(argv[0]);
		printf("dbsid must be specified!\n\n");
		return -1;
	}
	if (user == ""){
		usage(argv[0]);
		printf("dbuser must be specified!\n\n");
		return -1;
	}
	if (password == ""){
		usage(argv[0]);
		printf("dbpasswd must be specified!\n\n");
		return -1;
	}
	if (configFile == ""){
		usage(argv[0]);
		printf("config file must be specified!\n\n");
		return -1;
	}
	
	return 0;
}

void Wrapper::usage(char *name)
{
	printf("Usage:%s -i dbsid -u dbusr -p dbpwd -c configfile\n", name);
	printf("    -i dbsid      specify the SID to access oracle;\n");
	printf("    -u dbuser     specify the username to access oracle;\n");
	printf("    -p dbpasswd   specify the password to access oracle;\n");
	printf("    -c configfile specify the config file name ;\n");

	printf("\n\n");
}

int Wrapper::open()
{
	char connectionString[256];
	sprintf(connectionString, "%s/%s@%s", user.c_str(), password.c_str(), sid.c_str());
	connection = new Connection(connectionString);
	try{
		connection->open();
	}catch(Exception *e){
		error<<"oracode="<<e->code()<<endl<<e->what().c_str()<<endl;
		delete e;
		return -1;
	}
	
	tableMapping = new TableMapping(*connection, parameters);
	if (tableMapping->init(configFile.c_str()) != 0){
		error<<"tableMapping->init("<<configFile<<") error"<<endl;
		return -1;
	}
	
	const string &method = tableMapping->getMethod();
	if (method == "merge"){
		load = new Merge(*tableMapping, *connection);
	}else if (method == "append"){
		load = new Append(*tableMapping, *connection);
	}else if (method == "truncate"){
		load = new Truncate(*tableMapping, *connection);
	}else{
		error<<"invalid method, please check config file "<<configFile<<endl;
		return -1;
	}
						
	return 0;
}

void Wrapper::clear()
{
	if (load != 0){
		delete load;
		load = 0;
	}
	if  (tableMapping != 0){
		delete tableMapping;
		tableMapping = 0;
	}
	if (connection != 0){
		delete connection;
		connection = 0;
	}
}

int Wrapper::sigaction(int signum)
{
	struct sigaction act;
	act.sa_sigaction = 0;
	act.sa_handler = signalAbort;
	sigemptyset(&act.sa_mask);
	act.sa_flags = 0;
	act.sa_restorer = 0;
	if (::sigaction(signum, &act, 0) != 0){
		printf("sigaction error.errno=%d", errno);
		return -1;
	}
	return 0;
}

int Wrapper::sigaction()
{
	if (sigaction(SIGINT) != 0){
		return -1;
	}
	if (sigaction(SIGTERM) != 0){
		return -1;
	}
	if (sigaction(SIGQUIT) != 0){
		return -1;
	}
	if (sigaction(SIGABRT) != 0){
		return -1;
	}
	return 0;
}
